﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MigracionDeDatos
{
    class Program
    {
        static void CopiarDatosDe_UNIRGA_RTC()
        {
            db_Gestor origen = new db_Gestor();
            var query = from t in origen.tb_UNIRGA_RTC
                        where t.cBorrado.Equals("No")
                        select t;

            Destino destino = new Destino();

            foreach (tb_UNIRGA_RTC dat in query)
            {
                int idUniv = ObtenerIdUniversidad(destino, dat.sUniversidadAsignaturaExterna);
                if (idUniv != -1)
                {
                    ObtenerIdEstudio(destino, dat.sTitulacionAsignaturaExterna, idUniv);
                }
                else
                {
                    //throw new Exception("No se pudo ni encontrar ni crear una nueva universidad");
                }
            }
        }


        private static int ObtenerIdUniversidad(Destino destino, String nombre)
        {
            int resultado = -1;

            if (!String.IsNullOrEmpty(nombre))
            {
                var query = from t in destino.CentroEstudioExternoes
                            where t.Nombre.Equals(nombre)
                            select t;

                if (query.Count() > 0)
                {
                    resultado = ((CentroEstudioExternoes)query.First()).Id;
                }
                else
                {
                    destino.AddToCentroEstudioExternoes(new CentroEstudioExternoes() { Nombre = nombre,  IdRef = -1, ModifiedDate = DateTime.Now, Discriminator = "Universidad" });
                    destino.SaveChanges();
                    EscribirEnConsola("se agrego la universidad: " + nombre);
                    resultado = ObtenerIdUniversidad(destino, nombre);
                }
            }

            return resultado;
        }


        private static int? ObtenerIdEstudio(Destino destino, String nombre, int idCentroEstudio)
        {
            int? resultado = -1;
            if (!String.IsNullOrEmpty(nombre))
            {
                var query = from t in destino.EstudioExternoes
                            where t.Nombre.ToLower().Equals(nombre.ToLower()) && t.CentroEstudioExterno_Id == idCentroEstudio
                            select t;

                if (query.Count() > 0)
                {
                    resultado = ((EstudioExternoes)query.First()).Id;
                }
                else
                {
                    destino.AddToEstudioExternoes(new EstudioExternoes() { Nombre = nombre, CentroEstudioExterno_Id = idCentroEstudio, ModifiedDate = DateTime.Now });
                    destino.SaveChanges();
                    EscribirEnConsola("se agrego el estudio: " + nombre);
                    resultado = ObtenerIdEstudio(destino, nombre, idCentroEstudio);
                }
            }
            return resultado;
        }

        private static void CopiarEstudiosYAsignaturasUNIR()
        {
            db_Gestor origen = new db_Gestor();
            Destino destino = new Destino();

            foreach (tb_UNIRGA_Estudios asx in origen.tb_UNIRGA_Estudios)
            {
                destino.AddToEstudios(new Estudios() { Nombre = asx.sEstudioUNIR, IdRef = asx.idUNIRGAEstudios });
                EscribirEnConsola("agregando estudio: " + asx.sEstudioUNIR);
                destino.SaveChanges();
            }

            foreach (tb_UNIRGA_AsignaturasEstudios asx in origen.tb_UNIRGA_AsignaturasEstudios)
            {
                destino.AddToAsignaturas(new Asignaturas() { Nombre = asx.sDenominacionAsignatura, IdRef = asx.idUNIRGAAsignaturaEstudio });
                EscribirEnConsola("agregando asignatura: " + asx.sDenominacionAsignatura);
                destino.SaveChanges();
            }
        }


        public static void GenerarConvalidaciones()
        {
            db_Gestor origen = new db_Gestor();
            Destino destino = new Destino();
            int contador = 0;

            //primero solo registramos las convalidacione existentes
            var query = from t in origen.tb_UNIRGA_RTCAsigUNIR
                        where t.cBorrado.Equals("No") && !t.sRTCSinAsignatura.ToLower().Equals("SinAsignaturaExterna".ToLower())
                        select t;
            foreach (tb_UNIRGA_RTCAsigUNIR dat in query)
            {
                int idAsignatura = obtenerIdAsigByRef(dat.idUNIRGAAsignaturaEstudio, destino);
                destino.AddToConvalidacions(new Convalidacions() { Asignatura_Id = idAsignatura, TieneAsigExternas = true, IdRef = dat.idUNIRGARTCAsigUNIR, TieneEstudio = false});
                destino.SaveChanges();
                contador += 1;
                EscribirEnConsola("Se agrego nueva convalidación... " + contador.ToString());
            }

            // luego a cada convalidación le agregamos las asignaturas q correspondan ( si es q corresponden)
            var query2 = from ttt in origen.tb_UNIRGA_RTCAsigExternas
                         where ttt.cBorrado.Equals("No")
                         select ttt;

            foreach (tb_UNIRGA_RTCAsigExternas dat in query2)
            {
                int idConvalidacion = ObtenerIdConvalidacionByRef(dat.idUNIRGARTCAsigUNIR, destino);
                if (idConvalidacion != -1)
                {
                    int idAsignaturaExt = ObtenerIdAsignaturaExtByRef(dat.idUNIRGARTCAsigExterna, destino);
                    if (idAsignaturaExt != -1)
                    {
                        destino.AddToConvalidacionAsignaturas(new ConvalidacionAsignaturas() { AsignaturaExterna_Id = idAsignaturaExt, Convalidacion_Id = idConvalidacion });
                        destino.SaveChanges();
                        contador += 1;
                        EscribirEnConsola("Se agrego nueva convalidación asignatura... " + contador.ToString());
                    }
                }
            }

             //luego, volvemos  a realizar una pasada a las convalidaciones para establecaer el estudio....
            var query3 = from uuu in destino.ConvalidacionAsignaturas                         
                         select uuu;

            foreach (ConvalidacionAsignaturas dat in query3)
            {
                Convalidacions conv = (from o in destino.Convalidacions where o.Id == dat.Convalidacion_Id select o).First();
                conv.EstudioExterno_Id = dat.AsignaturaExternas.Estudio_Id;
                conv.TieneAsigExternas = true;

                contador += 1;
                EscribirEnConsola("Se establecion un estudio de una convalidacion... " + contador.ToString());
            }

            destino.SaveChanges();

            EscribirEnConsola("Se guardo correctamente...");
        }

        private static int ObtenerIdAsignaturaExtByRef(int p, Destino destino)
        {
            var resultado = -1;
            var query = from t in destino.AsignaturaExternas
                        where t.IdRef == p
                        select t;

            if (query.Count() > 0)
            {
                resultado = query.First<AsignaturaExternas>().Id;
            }
            return resultado;
        }

        private static int ObtenerIdConvalidacionByRef(int p, Destino destino)
        {
            var resultado = -1;
            var query = from t in destino.Convalidacions
                        where t.IdRef == p
                        select t;

            if (query.Count() > 0)
            {
                resultado = query.First<Convalidacions>().Id;
            }
            return resultado;
        }

        private static int obtenerIdAsigByRef(int p, Destino destino)
        {
            var resultado = -1;
            var query = from t in destino.Asignaturas
                        where t.IdRef == p
                        select t;

            if (query.Count() > 0)
            {
                resultado = query.First<Asignaturas>().Id;
            }
            return resultado;
        }

        static void Main(string[] args)
        {
            //PasarInformacionEstudios();
            //GenerarConvalidaciones();

            PasarInformacionEstudios();

            Console.WriteLine("Operacion finalizada");
            Console.ReadKey();

        }

        private static void PasarInformacionEstudios()
        {
            db_Gestor origen = new db_Gestor();
            Destino destino = new Destino();

            int registrosExplorados = 0;

            registrosExplorados = CopiarDatosDe_tb_UNIRGA_AsignaturasExternas(origen, destino, registrosExplorados);

            CopiarDatosDe_UNIRGA_RTC();

            CopiarEstudiosYAsignaturasUNIR();


            EscribirEnConsola("Registros explorados: " + registrosExplorados.ToString());
        }

        private static int CopiarDatosDe_tb_UNIRGA_AsignaturasExternas(db_Gestor origen, Destino destino, int registrosExplorados)
        {
            foreach (tb_UNIRGA_AsignaturasExternas asx in origen.tb_UNIRGA_AsignaturasExternas)
            {
                if (asx.cBorrado.Equals("No"))
                {
                    int idUniversidad = ObtenerIdUniversidad(destino, asx.sUniversidadAsignaturaExterna);
                    int? idEstudio = ObtenerIdEstudio(destino, asx.sTitulacionAsignaturaExterna, idUniversidad);
                    if (idUniversidad * idEstudio > 0)
                    {
                        int idAsig = ObtenerIdAsignatura(destino, asx.sDenominacionAsignaturaExterna, idEstudio);
                        if (idAsig == -1)
                        {
                            destino.AddToAsignaturaExternas(new AsignaturaExternas() { Nombre = asx.sDenominacionAsignaturaExterna, NroCreditos = Double.Parse(asx.iNumeroCreditos.ToString()), Estudio_Id = idEstudio, IdRef = asx.idUNIRGAAsignaturaExterna, ModifiedDate = DateTime.Now });
                            EscribirEnConsola("agregando: " + asx.sDenominacionAsignaturaExterna);
                            destino.SaveChanges();
                            registrosExplorados += 1;
                        }
                    }
                    else
                    {
                        throw new Exception("Error completo al copiar los datos");
                    }
                }
            }
            return registrosExplorados;
        }

        private static void EscribirEnConsola(string p)
        {
            Console.WriteLine(p);
        }

        private static int ObtenerIdAsignatura(Destino destino, string nombre, int? idEstudio)
        {
            int resultado = -1;
            if (!String.IsNullOrEmpty(nombre))
            {
                var query = from t in destino.AsignaturaExternas
                            where t.Nombre.ToLower().Equals(nombre.ToLower()) && t.Estudio_Id == idEstudio
                            select t;

                if (query.Count() > 0)
                {
                    resultado = ((AsignaturaExternas)query.First()).Id;
                }
            }
            return resultado;
        }
    }
}
